﻿// ———————————————————————–
// <copyright file="ValueListDAL.cs" company="The MITRE Corporation">
//    Copyright (c) 2010 The MITRE Corporation. All rights reserved.
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
// </copyright>
// ———————————————————————–
/////////////////////////////////////////////////////////////////////////////////////////////////
// ValueListDAL.cs - Data Access Layer For Retrieving Value List URI Constructs
// Project: IC.NETSOA- IC.NETDAL
//
// Language:    C#, .NET 4.0
// Platform:    Dell XPS m1530 Windows 7, VS 2010
// Author:      Don McGarry MITRE Rome
/////////////////////////////////////////////////////////////////////////////////////////////////

// Copyright (c) 2010 The MITRE Corporation. All rights reserved.
//
// NOTICE
// This software was produced for the U. S. Government
// under Contract No. FA8721-09-C-0001, and is
// subject to the Rights in Noncommercial Computer Software
// and Noncommercial Computer Software Documentation Clause
// (DFARS) 252.227-7014 (JUN 1995)
                
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using ICNETServices;

namespace ICNETDAL
{
  /// <summary>
  ///  This class contains methods that can be used to get values associated with a specific list name.
  /// </summary>
  public static class ValueListDAL
  {
    #region Public Member Functions

    /// <summary>
    /// Gets The Values Associated With A Specified ValueList.
    /// </summary>
    /// <param name="listname">Name Of The List In Path Form</param>
    /// <returns>An XML Element containing the  Values, Command Structure, and Description Information</returns>
    public static XElement GetValuesByListName(string listname)
    {
      int index = listname.LastIndexOf("/");
      string subname = listname.Substring(index + 1);
      XElement xe = new XElement(subname);
      ICNETValueListsDataContext valuelistdb = new ICNETValueListsDataContext(ICNETSOAConstants.ValueListsConnectionString);
      IQueryable values = from p in valuelistdb.IC_NETValueLists
                          where p.ValueListURI.StartsWith(listname)
                          select p;

      foreach (IC_NETValueList value in values)
      {
        xe.Add(new XElement("ValueInfo", new XElement("Value", value.Value), new XElement("CommandStructure", value.CommandStructure), new XElement("Description", value.Description)));
      }

      return xe;
    }

    /// <summary>
    /// Get the names of all of the ValueLists
    /// </summary>
    /// <returns>An XML object, containing the names of the ValueLists. </returns>
    public static XElement GetListNames()
    {
      ICNETValueListsDataContext valuelistdb = new ICNETValueListsDataContext(ICNETSOAConstants.ValueListsConnectionString);
      var valuelisturis = (from p in valuelistdb.IC_NETValueLists
                           select p.ValueListURI).Distinct();
      XElement xe = new XElement("ValueListURIs");
      foreach (var s in valuelisturis)
      {
        xe.Add(new XElement("ValueListURI", s.ToString()));
      }

      return xe;
    }

    /// <summary>
    /// Get all of the ValueLists.
    /// </summary>
    /// <returns>An XML object, containing all of the ValueLists.</returns>
    public static XElement GetValueLists()
    {
      ICNETValueListsDataContext valuelistdb = new ICNETValueListsDataContext(ICNETSOAConstants.ValueListsConnectionString);
      XElement xe = new XElement("ValueLists");
      var valuelists = from p in valuelistdb.IC_NETValueLists orderby p.ValueListURI select p;

      foreach (IC_NETValueList v in valuelists)
      {
        xe.Add(ValueListDAL.GetValueListXML(v));
      }

      return xe;
    }

    /// <summary>
    /// Get the names of all of the ValueLists given a simple string pattern (e.g., '/ValueLists/Roles/' which matches the SQL pattern '%/ValueLists/Roles/%' )
    /// </summary>
    /// <param name="pattern">specifies the pattern to match in the where clause (e.g., "/ValueLists/Roles/")</param>
    /// <returns>An XML object, containing the names of the ValueLists. </returns>
    public static XElement GetListNamesWithPattern( string pattern )
    {
        string subname = "Roles";
        XElement xe = new XElement(subname);
        ICNETValueListsDataContext valuelistdb = new ICNETValueListsDataContext(ICNETSOAConstants.ValueListsConnectionString);
        IQueryable values = (from p in valuelistdb.IC_NETValueLists
                            where p.ValueListURI.Contains(pattern)
                            select p.ValueListURI).Distinct();

        foreach (string value in values)
        {
            xe.Add(new XElement("ValueListURI", value.ToString()));
        }

//        ICNETValueListsDataContext valuelistdb = new ICNETValueListsDataContext(ICNETSOAConstants.ValueListsConnectionString);
//        var valuelisturis = from p in valuelistdb.IC_NETValueLists
//                             where p.ValueListURI.Contains(pattern)
//                             select p;

//        XElement xe = new XElement("ValueListURIs");
//        foreach (IC_NETValueList v in valuelisturis)
//        {
//            xe.Add(new XElement("ValueListURI", v.ToString()));
//        }

        return xe;
    }

    /// <summary>
    /// Looks up the ID for a ValueList.
    /// </summary>
    /// <param name="guid">A globallly unique identifier that corresponds to a ValueList. </param>
    /// <returns>An XML object containing the ValueList.</returns>
    public static XElement GetValueList(System.Guid guid)
    {
      ICNETValueListsDataContext valuelistdb = new ICNETValueListsDataContext(ICNETSOAConstants.ValueListsConnectionString);
      var vl = from vd in valuelistdb.IC_NETValueLists where vd.VLKey == guid select vd;
      if ((vl.Count() > 1) || (vl.Count() < 1))
      {
        return new XElement("ValueList", null);
      }

      IC_NETValueList v = vl.First();
      return ValueListDAL.GetValueListXML(v);
    }

    /// <summary>
    /// Deletes a ValueList from the database. Will return void if there are no items to be deleted. 
    /// </summary>
    /// <param name="guid">The GUID of the deleted ValueList.</param>
    public static void DeleteValueList(System.Guid guid)
    {
      ICNETValueListsDataContext valuelistdb = new ICNETValueListsDataContext(ICNETSOAConstants.ValueListsConnectionString);
      var value = from v in valuelistdb.IC_NETValueLists where v.VLKey == guid select v;
      if (value.Count() < 1)
      {
        return;
      }

      valuelistdb.IC_NETValueLists.DeleteOnSubmit(value.First());
      valuelistdb.SubmitChanges();
    }

   /// <summary>
   /// Adds a ValueList to the database. 
   /// </summary>
    /// <param name="valueListXML">A ValueList in the form of an XML element.</param>
    /// <returns>An XML element containing the value list and its ID, or an error if it was not sucesfully created.</returns>
    public static XElement CreateValueList(XElement valueListXML)
    {
      ICNETValueListsDataContext valuelistdb = new ICNETValueListsDataContext(ICNETSOAConstants.ValueListsConnectionString);
      try
      {
        string uri = valueListXML.Descendants("ValueListURI").First().Value;
        string val = valueListXML.Descendants("Value").First().Value;
        string cstruc = valueListXML.Descendants("CommandStructure").First().Value;
        string desc = valueListXML.Descendants("Description").First().Value;

        if ((uri == string.Empty) || (val == string.Empty))
        {
          return new XElement("ValueListError", "ValueListURI and Value must be specified.");
        }

        var vls = from vl in valuelistdb.IC_NETValueLists
                    where vl.ValueListURI == uri &&
                       vl.Value == val &&
                       vl.CommandStructure == cstruc &&
                       vl.Description == desc
                    select vl;
        if (vls.Count() > 0)
        {
          return ValueListDAL.GetValueListXML(vls.First());
        }

        IC_NETValueList v = new IC_NETValueList { VLKey = System.Guid.NewGuid(), ValueListURI = uri, Value = val, CommandStructure = cstruc, Description = desc };
        valuelistdb.IC_NETValueLists.InsertOnSubmit(v);
        valuelistdb.SubmitChanges();
        return ValueListDAL.GetValueListXML(v);
      }
      catch (InvalidOperationException)
      {
        return new XElement("ValueListError", "ValueListURI and Value must be specified.");
      }
    }

    /// <summary>
    /// Modifies a ValueList in the ValueList Database
    /// </summary>
    /// <param name="valueListXML">The ValueList, in XML format, that should be modified in the database</param>
    /// <returns> IF the inputted ValueList was properly formatted, it will be returned as an XML object with a new GUID
    /// If the inputted ValueList is improperly formatted, then an XML object will be returned, but not added to the database</returns>


    public static XElement ModifyValueList(XElement valueListXML, System.Guid guid)
    {
        ICNETValueListsDataContext valuelistdb = new ICNETValueListsDataContext(ICNETSOAConstants.ValueListsConnectionString);

        var modvalue = from vd in valuelistdb.IC_NETValueLists where vd.VLKey == guid select vd; 
        try
        {
            string uri = valueListXML.Descendants("ValueListURI").First().Value;
            string val = valueListXML.Descendants("Value").First().Value;
            string cstruc = valueListXML.Descendants("CommandStructure").First().Value;
            string desc = valueListXML.Descendants("Description").First().Value;

            if ((uri == string.Empty) || (val == string.Empty))
            {
                return new XElement("ValueListError", "ValueListURI and Value must be specified.");
            }

            IC_NETValueList v = modvalue.First();

            v.ValueListURI = uri;
            v.Value = val;
            v.CommandStructure = cstruc;
            v.Description = desc;

            valuelistdb.SubmitChanges();
            return ValueListDAL.GetValueListXML(v);
        }
        catch (InvalidOperationException)
        {
            return new XElement("ValueListError", "ValueListURI and Value must be specified.");
        }

    }




   /// <summary>
   /// Takes a ValueList out of the ICNET database and transforms it into raw XML
   /// </summary>
   /// <param name="v">the ICNET formatted ValueList</param>
   /// <returns>an XML object that contains the ValueList, it'serializer key, it'serializer uri, it'serializer value, it'serializer description, and it'serializer command structure.</returns>
    public static XElement GetValueListXML(IC_NETValueList v)
    {
      return new XElement("ValueList", new XElement("VLKey", v.VLKey), new XElement("ValueListURI", v.ValueListURI), new XElement("Value", v.Value), new XElement("CommandStructure", v.CommandStructure), new XElement("Description", v.Description));
    }

    #endregion

    #region Protected Member Functions
    
    #endregion

    #region Private Member Functions
   
    #endregion         
  }
}
